#define _XOPEN_SOURCE  

#include "threadpool.h"
#include "transferfile.h"
#include "linkedlist.h"
#include "tools.h"

#define rowNum 8

extern int epfd;
extern UserList* userList;

char cmds[rowNum][8]={"cd", "ls", "pwd", "puts", "gets", "rm", "mkdir", "quit"};

void threadpoolInit(thread_pool_t* pthreadpool, int threadNum)
{
	pthreadpool->threadNumber = threadNum;
	pthreadpool->threads = (pthread_t*)calloc(threadNum, sizeof(pthread_t));
	queueInit(&pthreadpool->queue);
}

void threadpoolDestroy(thread_pool_t* pthreadpool)
{
	free(pthreadpool->threads);
	queueDestroy(&pthreadpool->queue);
}

void threadpoolStart(thread_pool_t * pthreadpool)
{
	for(int idx = 0; idx < pthreadpool->threadNumber; ++idx) {
		int ret = pthread_create(&pthreadpool->threads[idx],
			NULL, 
			threadFunc, 
			pthreadpool);
		THREAD_ERROR_CHECK(ret, "pthread_create");
	}
}

void * threadFunc(void* arg)
{
	//每一个子线程要做的事儿
	printf("sub thread %ld is runing\n", pthread_self());
	thread_pool_t * pthreadpool = (thread_pool_t*)arg;
	
    while(1) {
        task_t task;
		taskDequeue(&pthreadpool->queue, &task);
        
        if(task.peerfd>0){
            handleTask(&task);
            
            // 任务完成, 让主线程恢复监听
            epollAddReadEvent(epfd, task.peerfd); 
        }else{
            break;
        }
	}
	printf("sub thread %ld is ready to exit\n", pthread_self());
	pthread_exit(0);
}

void handleTask(task_t* ptask){
    //根据任务类型调用不同的处理函数
    if(ptask->taskType==TASK_REGISTER){
        handleRegisterTask(ptask);
    }else if(ptask->taskType==TASK_LOGIN){
        handleLoginTask(ptask);
    }else if(ptask->taskType==TASK_COMMAND){
        handleCommandTask(ptask);
    }
    
}

void handleRegisterTask(task_t *ptask){
    train_t train;
    char recvbuf[NETBUFSIZE];
    char username[30];
    char salt[20];
    char cryptpasswd[100];
    char passwd[100];

    //从客户端获取用户名
    memset(train.data,'\0',NETBUFSIZE);
    strcpy(train.data,"-------------------用户注册界面-------------------\n>> 请输入用户名:");
    train.length=getLength(train.data);                     
    sendn(ptask->peerfd, &train, 8+train.length);
    
    memset(recvbuf,'\0',sizeof(recvbuf));
    int ret = recv(ptask->peerfd, recvbuf, sizeof(recvbuf), 0);
    if(ret > 0){
        memset(username,'\0',sizeof(username));
        memcpy(username, recvbuf, getLength(recvbuf));
        username[getLength(username)-1] = '\0';
        printf("username: %s\n", username);
    }

    //从客户端获取密码
    memset(train.data, '\0', NETBUFSIZE);
    strcpy(train.data, ">> 请输入密码:");
    train.length=getLength(train.data);                     
    sendn(ptask->peerfd, &train, 8+train.length);
    
    memset(recvbuf, '\0', sizeof(recvbuf));
    ret = recv(ptask->peerfd, recvbuf, sizeof(recvbuf), 0);
    if(ret > 0){
        memset(passwd, '\0', sizeof(passwd));
        memcpy(passwd, recvbuf, getLength(recvbuf));
        passwd[getLength(passwd)-1] = '\0';
        printf("passwd: %s\n", passwd);
    }

    //生成盐值
    memset(salt,'\0',sizeof(salt));
    generate_str(salt);
    printf("salt: %s\n",salt);

    //密码和盐值加密
    strcpy(cryptpasswd, crypt(passwd, salt));
    printf("cryptpasswd: %s\n", cryptpasswd);
    
    //将用户名、盐值、加密密码、pwd存入数据库
    char sql[100];
    MYSQL_RES* result;

    memset(sql, '\0', sizeof(sql));
    sprintf(sql, "insert into User(username, salt, cryptpasswd, pwd) value('%s', '%s', '%s', '/%s/')", username, salt, cryptpasswd, username);
    
    printf("sql: %s\n", sql);
    
    result=myQuery(sql);
    if(ret > 0){
        printf("插入数据库成功!\n");
    }
    
    memset(train.data, '\0', NETBUFSIZE);
    strcpy(train.data, ">> 注册成功！\n");
    train.length = getLength(train.data);                     
    sendn(ptask->peerfd, &train, 8+train.length);

    //从数据库查询用户id
    memset(sql, '\0', sizeof(sql));
    sprintf(sql, "select id from User where username='%s'", username);
    
    result=myQuery(sql);
    if(ret > 0){
        printf("查询数据库成功!\n");
    }
    
    MYSQL_ROW row = mysql_fetch_row(result);
    
    int id = atoi(row[0]);
    
    //在虚拟文件表中给用户创建一个文件目录
    memset(sql, '\0', sizeof(sql));
    sprintf(sql, "insert into VirtualFile(parent_id, filename, owner_id, md5, filesize, type) value(0, '%s', %d, 0, 0, 'd')", username, id);
    
    printf("sql: %s\n", sql);
    
    result = myQuery(sql);
    if(ret > 0){
        printf("插入数据库成功!\n");
    }
    
    // 释放结果集
    mysql_free_result(result);

    //回到用户登录注册界面
    memset(train.data,'\0',NETBUFSIZE);
    strcpy(train.data,"-------------------登录注册界面-------------------\n1. 登录\n2. 注册\n请输入'1'或'2':");
    train.length=getLength(train.data);                     
    sendn(ptask->peerfd, &train, 8+train.length);
}

void handleLoginTask(task_t *ptask){
    train_t train;
    char recvbuf[NETBUFSIZE];
    char username[30];
    char salt[20];
    char cryptpasswd[100];
    char passwd[100];
    
    //从客户端获取用户名
    memset(train.data,'\0',NETBUFSIZE);
    strcpy(train.data,"-------------------用户登录界面-------------------\n>> 请输入用户名:");
    train.length=getLength(train.data);                     
    sendn(ptask->peerfd, &train, 8+train.length);
    
    memset(recvbuf,'\0',strlen(recvbuf));
    int ret = recv(ptask->peerfd, recvbuf, sizeof(recvbuf), 0);
    if(ret>0){
        memset(username,'\0',sizeof(username));
        memcpy(username,recvbuf,getLength(recvbuf));
        username[getLength(username)-1] = '\0';
        printf("username: %s\n",username);
    }
    
    //从数据库查询salt
    char sql[100];
    MYSQL_RES* result;
    memset(sql,'\0',sizeof(sql));
    sprintf(sql, "select salt from User where username='%s'", username);
    
    printf("sql: %s\n", sql);

    result=myQuery(sql);
    if(ret > 0){
        printf("查询数据库成功!\n");
    }

    MYSQL_ROW row = mysql_fetch_row(result);
    memset(salt,'\0', sizeof(salt));
    strcpy(salt, row[0]);
    printf("salt: %s\n", salt);
    
    //将salt发送给客户端
    memset(train.data,'\0',NETBUFSIZE);
    strcpy(train.data, salt);
    train.dataType=1;
    train.length=getLength(train.data);                     
    sendn(ptask->peerfd, &train, 8+train.length);
    
    memset(recvbuf,'\0',strlen(recvbuf));
    ret = recv(ptask->peerfd, recvbuf, sizeof(recvbuf), 0);
    if(ret > 0){
        memset(cryptpasswd,'\0',sizeof(cryptpasswd));
        memcpy(cryptpasswd,recvbuf,getLength(recvbuf));
        printf("cryptpasswd: %s\n",cryptpasswd);
    }
    
    //从数据库查询id, cryptpasswd
    memset(sql,'\0',sizeof(sql));
    sprintf(sql,"select id, cryptpasswd from User where username='%s'", username);
    
    printf("sql: %s\n", sql);
    
    result=myQuery(sql);
    if(ret > 0){
        printf("查询数据库成功!\n");
    }
    
    row=mysql_fetch_row(result);
    
    int id = atoi(row[0]);

    memset(passwd,'\0',sizeof(passwd));
    strcpy(passwd, row[1]);
    printf("用户id: %d, passwd: %s\n", id, passwd);
    
    // 释放结果集
    mysql_free_result(result);
    
    //比较密码是否匹配
    if(strcmp(passwd, cryptpasswd) == 0){
        printf("用户 %s 登录成功！\n",username);
        
        //将peerfd和用户id保存到已经登录的用户链表
        add_behind_rear(userList, ptask->peerfd, id);
        printf("userList size: %d\n", userList->size);

        memset(train.data, '\0', NETBUFSIZE);
        strcpy(train.data, "登录成功!\n");
        train.length = getLength(train.data);                     
        train.dataType = 0;
        sendn(ptask->peerfd, &train, 8+train.length);
        
        //转到命令交互界面
        memset(train.data, '\0', NETBUFSIZE);
        strcpy(train.data, "-------------------命令交互界面-------------------\n>> 请输入命令\n支持的命令: cd、ls、pwd、puts、gets、rm、mkdir");
        train.length=getLength(train.data);                     
        sendn(ptask->peerfd, &train, 8+train.length);
    
    }else{
        printf("用户 %s 登录失败！\n", username);
        
        memset(train.data, '\0', NETBUFSIZE);
        strcpy(train.data, "登录失败!\n");
        train.length = getLength(train.data);                     
        train.dataType = 0;
        sendn(ptask->peerfd, &train, 8+train.length);
    
        //回到用户登录注册界面
        memset(train.data,'\0',NETBUFSIZE);
        strcpy(train.data,"-------------------登录注册界面-------------------\n1. 登录\n2. 注册\n请输入'1'或'2':");
        train.length=getLength(train.data);                     
        sendn(ptask->peerfd, &train, 8+train.length);

    }

}

void handleCommandTask(task_t *ptask){
    train_t train;
    command_t command;
    
    printf("command: %s\n", ptask->command);
    
    //解析命令
    parse_cmd(ptask->command, &command);
    printf("command_t: %s, %s\n", command.cmd, command.parameter);
    
    int i = 0;
    int flag = 0;
    for(i = 0; i < rowNum && flag == 0; i++){
        if(strcmp(cmds[i], command.cmd) == 0){
            flag = 1;
            switch (i) {
            case 0:
                cmd_cd(ptask->peerfd, command.parameter);
                break;
            case 1:
                cmd_ls(ptask->peerfd);
                break;
            case 2:
                cmd_pwd(ptask->peerfd);
                break;
            case 3:
                cmd_puts(ptask->peerfd, command.parameter);
                break;
            case 4:
                cmd_gets(ptask->peerfd, command.parameter);
                break;
            case 5:
                cmd_rm(ptask->peerfd, command.parameter);
                break;
            case 6:
                cmd_mkdir(ptask->peerfd, command.parameter);
                break;
            case 7:
                cmd_quit(ptask->peerfd);
                break;
            default:
                ;
            }
        }
    }

    if(flag == 0){
        printf("不合法的命令!\n");
       
        train.dataType = 0;
        memset(train.data,'\0',NETBUFSIZE);
        train.length=strlen("不合法的命令，请重新输入!");
        memcpy(train.data,"不合法的命令，请重新输入!",train.length);
        sendn(ptask->peerfd, &train, 8+train.length);

    }
}

void cmd_cd(int peerfd, char* parameter)
{
    train_t train;
    
    char sql[100];
    MYSQL_RES* result;
    
    // 从用户链表中查询用户id
    int user_id = search(userList, peerfd);

    //从数据库查询该用户的当前工作目录
    char pwd[100];
    memset(pwd,'\0', sizeof(pwd));
    get_pwd(user_id, pwd);
    printf("pwd: %s\n", pwd);

    // 解析 pwd 获取 dir_id
    int dir_id = parse_pwd(pwd);
    printf("dir_id: %d\n", dir_id);

    memset(train.data,'\0', sizeof(train.data));
    printf("parameter: %s, length: %ld\n", parameter, strlen(parameter));
    if(strcmp(parameter, "..") == 0){
        pwd_up(pwd);

        // 更新 User 表的 pwd
        memset(sql, '\0', sizeof(sql));
        sprintf(sql, "update User set pwd = '%s'", pwd);
        printf("sql: %s\n", sql);
    
        result = myQuery(sql);
                
        strcpy(train.data, pwd);
        
    }else{
        //从数据库查询该用户的当前工作目录下的文件夹
        memset(sql, '\0', sizeof(sql));
        sprintf(sql, "select filename from VirtualFile where filename = '%s' and owner_id = %d and parent_id = %d and type = 'd' ", parameter, user_id, dir_id);
        printf("sql: %s\n", sql);

        result = myQuery(sql);
    
        MYSQL_ROW row = mysql_fetch_row(result);
    
        // 是否存在该文件夹
        if(strcmp(row[0], parameter) == 0){
            strcat(pwd, row[0]);
            strcat(pwd, "/");
            printf("pwd: %s\n", pwd);
    
            // 更新 User 表的 pwd
            memset(sql, '\0', sizeof(sql));
            sprintf(sql, "update User set pwd = '%s' where id = %d", pwd, user_id);
            printf("sql: %s\n", sql);
    
            result = myQuery(sql);
            
            strcpy(train.data, pwd);
            printf("执行到这里2\n");
        
        }else{
            strcpy(train.data, "该文件夹不存在！");
        }

    }
    
    // 释放结果集
    mysql_free_result(result);
    
    // 将结果发送给客户端
    train.length=strlen(train.data);
    train.dataType = 0;
    sendn(peerfd, &train, 8+train.length);

}

void cmd_ls(int peerfd){
    //从数据库查询当前目录下的文件
    char sql[100];
    MYSQL_RES* result;
    MYSQL_ROW row;
    
    // 从用户链表中查询用户id
    int user_id = search(userList, peerfd);

    //从数据库查询该用户的当前工作目录
    char pwd[100];
    memset(pwd,'\0', sizeof(pwd));
    get_pwd(user_id, pwd);
    printf("pwd: %s\n", pwd);

    // 解析 pwd 获取 dir_id
    int dir_id = parse_pwd(pwd);
    printf("dir_id: %d\n", dir_id);
    
    // 用parent_id、owner_id查询当前工作目录下的文件夹和文件
    memset(sql, '\0', sizeof(sql));
    sprintf(sql, "select filename, owner_id, filesize, type from VirtualFile where parent_id = %d and owner_id = %d", dir_id, user_id);
    printf("sql: %s\n", sql);

    result=myQuery(sql);

    int rows = mysql_num_rows(result);
	int cols = mysql_num_fields(result);
	printf("rows:%d, cols:%d\n", rows, cols);

    // 将查询结果放入发送缓冲区
    char lsBuf[NETBUFSIZE];
    memset(lsBuf, '\0', sizeof(lsBuf));
    int lsBuf_size = 0;
    int ret = 0;

    ret = sprintf(lsBuf, "filename        owner_id        filesize        type\n");
    lsBuf_size += ret;
    while((row = mysql_fetch_row(result)) != NULL) {
        ret = sprintf(lsBuf+lsBuf_size,"%-20s%-10s%-20s%-10s\n", row[0], row[1], row[2], row[3]);
        lsBuf_size += ret;
	}
    
	printf("lsBuf:\n%s\n", lsBuf);
    
    // 释放结果集
    mysql_free_result(result);
    
    // 将结果发送给客户端
    train_t train;
    memset(train.data,'\0', sizeof(train.data));
    strcpy(train.data, lsBuf);
    train.length=strlen(train.data);
    train.dataType = 0;
    sendn(peerfd, &train, 8+train.length);
}

void cmd_pwd(int peerfd)
{
    // 从用户链表中查询用户id
    int user_id = search(userList, peerfd);

    //从数据库查询该用户的当前工作目录
    char pwd[100];
    memset(pwd,'\0', sizeof(pwd));
    get_pwd(user_id, pwd);
    printf("pwd: %s\n", pwd);

    // 解析 pwd 获取 dir_id
    int dir_id = parse_pwd(pwd);
    printf("dir_id: %d\n", dir_id);
    
    // 将结果发送给客户端
    train_t train;
    memset(train.data,'\0', sizeof(train.data));
    strcpy(train.data, pwd);
    train.length=strlen(train.data);
    train.dataType = 0;
    sendn(peerfd, &train, 8+train.length);
}

void cmd_puts(int peerfd, char* parameter){
    train_t train;
    char buff[NETBUFSIZE];

    // 通知客户端传md5
    memset(train.data,'\0', sizeof(train.data));
    strcpy(train.data, parameter);
    train.length = strlen(train.data);
    train.dataType = 3;
    sendn(peerfd, &train, 8+train.length);
    
    // 从客户端接收文件的md5
    int length;
    int dataType;
    char md5[100];

    recv(peerfd, &length, 4, MSG_WAITALL);
    recv(peerfd, &dataType, 4, MSG_WAITALL);
    memset(buff, '\0', sizeof(buff));
    recv(peerfd, buff, length, MSG_WAITALL);
    
    strcpy(md5, buff);

    printf("%s md5: %s\n", parameter, md5);
    
    //从数据库查询该用户的当前工作目录
    int user_id = search(userList, peerfd);
    
    char pwd[100];
    memset(pwd,'\0', sizeof(pwd));
    get_pwd(user_id, pwd);
    printf("pwd: %s\n", pwd);
    
    // 解析 pwd 获取 dir_id
    int dir_id = parse_pwd(pwd);
    printf("dir_id: %d\n", dir_id);
    
    // 查看当前工作目录是否存在该文件
    char sql[100];
    MYSQL_RES* result;
    
    memset(sql,'\0',sizeof(sql));
    sprintf(sql, "select id, filesize from VirtualFile where md5 = '%s' and parent_id = %d", md5, dir_id);
    printf("sql: %s\n", sql);

    result = myQuery(sql);
    MYSQL_ROW row = mysql_fetch_row(result);
    
    if(row == NULL){
        // 查看数据库里是否存在该文件
        memset(sql,'\0',sizeof(sql));
        sprintf(sql, "select id, filesize from VirtualFile where md5 = '%s' and parent_id", md5);
        printf("sql: %s\n", sql);

        result = myQuery(sql);
        row = mysql_fetch_row(result);

        int filesize;
        int flag = 0;
        if(row == NULL){
            printf("here 1\n");
        
            //通知客户端可以传文件
            memset(train.data,'\0', sizeof(train.data));
            strcpy(train.data, "ack");
            train.length = strlen(train.data);
            train.dataType = 3;
            sendn(peerfd, &train, 8+train.length);
        
            //进入上传界面
            filesize = upload_file(peerfd);
            printf("filesize: %d\n", filesize);

            flag = 1;
        
        }else {
            printf("here 2\n");
            filesize = atoi(row[1]);

            //通知客户端不用传文件, 实现文件秒传功能
            memset(train.data,'\0', sizeof(train.data));
            strcpy(train.data, "skip");
            train.length = strlen(train.data);
            train.dataType = 3;
            sendn(peerfd, &train, 8+train.length);
        }
    
        //更新虚拟文件表
    
        //插入文件记录
        memset(sql, '\0', sizeof(sql));
        sprintf(sql, "insert into VirtualFile(parent_id, filename, owner_id, md5, filesize, type) value(%d, '%s', %d, '%s', %d, 'f')", dir_id, parameter, user_id, md5, filesize);
        printf("sql: %s\n", sql);
    
        result = myQuery(sql);
    
    }else{
        //通知客户端文件已存在
        memset(train.data,'\0', sizeof(train.data));
        strcpy(train.data, "当前文件夹下已有相同的文件");
        train.length = strlen(train.data);
        train.dataType = 0;
        sendn(peerfd, &train, 8+train.length);

    }

    // 释放结果集
    mysql_free_result(result);
    

}

void cmd_gets(int peerfd, char* parameter){
    train_t train;
    
    //从数据库查询该用户pwd
    char sql[100];
    MYSQL_RES* result;
    
    // 从用户链表中查询用户id
    int user_id = search(userList, peerfd);

    //从数据库查询该用户的当前工作目录
    char pwd[100];
    memset(pwd,'\0', sizeof(pwd));
    get_pwd(user_id, pwd);
    printf("pwd: %s\n", pwd);

    // 解析 pwd 获取 dir_id
    int dir_id = parse_pwd(pwd);
    printf("dir_id: %d\n", dir_id);

    //查看该用户当前目录下的所有文件
    memset(sql, '\0', sizeof(sql));
    sprintf(sql, "select filename from VirtualFile where parent_id = %d and owner_id = %d and type = 'f'", dir_id, user_id);
    printf("sql: %s\n", sql);
    
    result = myQuery(sql);
    
    int flag = 0;
    MYSQL_ROW row;
    while((row = mysql_fetch_row(result)) != NULL) {
        if(strcmp(row[0], parameter) == 0){
            //若存在，进入下载界面
            download_file(peerfd, parameter);
            flag = 1;
        }
    }

    if(flag == 0){
        strcpy(train.data, "该文件不存在！");
        train.length=strlen(train.data);
        train.dataType = 0;
        sendn(peerfd, &train, 8+train.length);
    }
    
    // 释放结果集
    mysql_free_result(result);
    
}

void cmd_rm(int peerfd, char* parameter){
    //从数据库查询当前目录下有没有这个文件
    char sql[100];
    MYSQL_RES* result;
    
    // 从用户链表中查询用户id
    int user_id = search(userList, peerfd);

    //从数据库查询该用户的当前工作目录
    char pwd[100];
    memset(pwd,'\0', sizeof(pwd));
    get_pwd(user_id, pwd);
    printf("pwd: %s\n", pwd);

    // 解析 pwd 获取 dir_id
    int dir_id = parse_pwd(pwd);
    printf("dir_id: %d\n", dir_id);

    //从数据库查询该用户的当前工作目录下的文件夹和文件
    memset(sql, '\0', sizeof(sql));
    sprintf(sql, "select id, filename, type from VirtualFile where filename = '%s' and owner_id = %d and parent_id = %d", parameter, user_id, dir_id);
    printf("sql: %s\n", sql);

    result = myQuery(sql);
    
    MYSQL_ROW row;
    row = mysql_fetch_row(result);

    // 是否存在该文件或文件夹
    train_t train;
    memset(train.data,'\0', sizeof(train.data));
    if(row != NULL){    
        if(strcmp(row[1], parameter) == 0){
            //判断是文件还是文件夹
            if(strcmp(row[2], "d") == 0){
                //从虚拟文件表中删除该文件夹
                memset(sql, '\0', sizeof(sql));
                sprintf(sql, "delete from VirtualFile where owner_id = %d and parent_id = %d and filename = '%s'", user_id, dir_id, parameter);
                printf("sql: %s\n", sql);

                result=myQuery(sql);
                
                //从虚拟文件表中删除该文件夹下面的所有文件
                memset(sql, '\0', sizeof(sql));
                sprintf(sql, "delete from VirtualFile where owner_id = %d and parent_id = '%s'", user_id, row[0]);
                printf("sql: %s\n", sql);

                result=myQuery(sql);

            }else if(strcmp(row[2], "f") == 0){
                //从虚拟文件表中删除该文件
                memset(sql, '\0', sizeof(sql));
                sprintf(sql, "delete from VirtualFile where owner_id = %d and parent_id = %d and filename = '%s'", user_id, dir_id, parameter);
                printf("sql: %s\n", sql);

                result=myQuery(sql);
            }
            
            strcpy(train.data, "删除成功!");
        
        }
    }else{
        strcpy(train.data, "该文件不存在！");
    }
    
    // 释放结果集
    mysql_free_result(result);
    
    // 将结果发送给客户端
    train.length=strlen(train.data);
    train.dataType = 0;
    sendn(peerfd, &train, 8+train.length);

}

void cmd_mkdir(int peerfd, char* parameter){
    //从数据库查询当前目录下有没有这个文件
    char sql[100];
    MYSQL_RES* result;
    
    // 从用户链表中查询用户id
    int user_id = search(userList, peerfd);

    //从数据库查询该用户的当前工作目录
    char pwd[100];
    memset(pwd,'\0', sizeof(pwd));
    get_pwd(user_id, pwd);
    printf("pwd: %s\n", pwd);

    // 解析 pwd 获取 dir_id
    int dir_id = parse_pwd(pwd);
    printf("dir_id: %d\n", dir_id);

    //向virualfile表插入一个文件夹
    memset(sql, '\0', sizeof(sql));
    sprintf(sql, "insert into VirtualFile(parent_id, filename, owner_id, md5, filesize, type) value(%d, '%s', %d, 0, 0, 'd')", dir_id, parameter, user_id);
    printf("sql: %s\n", sql);
    
    result = myQuery(sql);
    
    // 释放结果集
    mysql_free_result(result);
    
    // 将结果发送给客户端
    train_t train;
    memset(train.data,'\0', sizeof(train.data));
    strcpy(train.data, "新建文件夹成功!");
    train.length=strlen(train.data);
    train.dataType = 0;
    sendn(peerfd, &train, 8+train.length);

}

void cmd_quit(int peerfd){
    train_t train;

    // 从已登录用户链表中删除
    delete_node(userList, peerfd);
    printf("userList size: %d\n", userList->size);

    //回到用户登录注册界面
    memset(train.data,'\0',NETBUFSIZE);
    strcpy(train.data,"-------------------登录注册界面-------------------\n1. 登录\n2. 注册\n请输入'1'或'2':");
    train.length=getLength(train.data);
    train.dataType = 0;
    sendn(peerfd, &train, 8+train.length);

}

// 解析 pwd 获取当前工作目录的文件夹id
int parse_pwd(char* pwd){
    //从数据库查询当前目录下的文件
    char sql[100];
    MYSQL_RES* result;

    char dir_name[50];

    int dir_id;
    int parent_id = 0;

    for(int i = 0; i < getLength(pwd) - 1; i++){
        char ch = pwd[i];
        //printf("ch: %c\n", ch);

        if(ch == '/'){
            i++;
            ch = pwd[i];
            memset(dir_name, '\0', sizeof(dir_name));
            while(ch != '/' && ch != '\0' ){
                concat(getLength(dir_name), dir_name, ch);
                //printf("dir: %d, %s\n", getLength(dir_name), dir_name);
                i++;
                ch = pwd[i];
            }
            i--;
            
            //从数据库查询该文件夹的id
            memset(sql, '\0', sizeof(sql));
            sprintf(sql, "select id from VirtualFile where parent_id = %d and filename = '%s' and type = 'd'", parent_id, dir_name);
            printf("sql: %s\n", sql);
 
            result=myQuery(sql);
 
            MYSQL_ROW row = mysql_fetch_row(result);
            
            dir_id = atoi(row[0]);
            
            parent_id = dir_id;

        }
    }
    
    // 释放结果集
    mysql_free_result(result);

    printf("解析pwd结束！\n");

    return dir_id;
}

void pwd_up(char* pwd){
    
    int cnt = 0;
    for(int i = getLength(pwd)-2; i > 0; i--){
        char ch = pwd[i];
        printf("ch: %c\n", ch);
        if(ch != '/'){
            cnt++;
        }else{
            break;
        }
    }

    if(getLength(pwd) != (cnt+2)){
        printf("执行memset\n");
        memset(pwd+getLength(pwd)-cnt-1, '\0', cnt+1);
        printf("pwd: %s\n", pwd);
    }

}
